package com.haixiaoke.saas.role.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.common.annotation.DataScope;
import com.haixiaoke.saas.common.constant.UserConstants;
import com.haixiaoke.saas.common.core.domain.entity.SysMenu;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.StringUtils;
import com.haixiaoke.saas.tenant.service.ITenantMenuService;
import com.haixiaoke.saas.role.domain.Role;
import com.haixiaoke.saas.role.domain.RoleDept;
import com.haixiaoke.saas.role.domain.RoleMenu;
import com.haixiaoke.saas.role.mapper.RoleMapper;
import com.haixiaoke.saas.role.service.IRoleDeptService;
import com.haixiaoke.saas.role.service.IRoleMenuService;
import com.haixiaoke.saas.role.service.IRoleService;
import com.haixiaoke.saas.system.service.ISysMenuService;
import com.haixiaoke.saas.user.domain.UserRole;
import com.haixiaoke.saas.user.service.IUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 企业端角色信息Service业务层处理
 *
 * @author panda
 * @date 2023-12-29
 */
@Service
public class RoleServiceImpl implements IRoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private IRoleMenuService iRoleMenuService;
    @Autowired
    private IUserRoleService iBizUserRoleService;
    @Autowired
    private IRoleDeptService iRoleDeptService;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private ITenantMenuService iTenantMenuService;

    /**
     * 查询企业端角色信息
     *
     * @param roleId 企业端角色信息主键
     * @return 企业端角色信息
     */
    @Override
    public Role selectBizRoleByRoleId(Long roleId) {
        return roleMapper.selectBizRoleByRoleId(roleId);
    }

    /**
     * 查询企业端角色信息列表
     *
     * @param role 企业端角色信息
     * @return 企业端角色信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<Role> selectBizRoleList(Role role) {
        return roleMapper.selectBizRoleList(role);
    }

    /**
     * 新增企业端角色信息
     *
     * @param role 企业端角色信息
     * @return 结果
     */
    @Override
    public int insertBizRole(Role role) {
        role.setCreateTime(DateUtils.getNowDate());
        roleMapper.insertBizRole(role);
        return insertRoleMenu(role);
    }

    /**
     * 新增角色菜单信息
     *
     * @param role 角色对象
     */
    public int insertRoleMenu(Role role) {
        int rows = 1;
        // 新增用户与角色管理
        List<RoleMenu> list = new ArrayList<RoleMenu>();
        for (Long menuId : role.getMenuIds()) {
            RoleMenu rm = new RoleMenu();
            rm.setRoleId(role.getRoleId());
            rm.setMenuId(menuId);
            list.add(rm);
        }
        if (!list.isEmpty()) {
            rows = iRoleMenuService.insertBatchRoleMenu(list);
        }
        return rows;
    }

    /**
     * 修改企业端角色信息
     *
     * @param role 企业端角色信息
     * @return 结果
     */
    @Override
    public int updateBizRole(Role role) {
        role.setUpdateTime(DateUtils.getNowDate());
        return roleMapper.updateBizRole(role);
    }

    /**
     * 批量删除企业端角色信息
     *
     * @param roleIds 需要删除的企业端角色信息主键
     * @return 结果
     */
    @Override
    public int deleteBizRoleByRoleIds(Long[] roleIds) {
        for (Long roleId : roleIds) {
            checkRoleDataScope(roleId);
            Role role = selectBizRoleByRoleId(roleId);
            if (iBizUserRoleService.countUserRoleByRoleId(roleId) > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName()));
            }
        }
        // 删除角色与菜单关联
        iRoleMenuService.deleteBizRoleMenuByRoleIds(roleIds);
        // 删除角色与部门关联
        iRoleDeptService.deleteBizRoleDeptByRoleIds(roleIds);
        return roleMapper.deleteBizRoleByRoleIds(roleIds);
    }

    /**
     * 删除企业端角色信息信息
     *
     * @param roleId 企业端角色信息主键
     * @return 结果
     */
    @Override
    public int deleteBizRoleByRoleId(Long roleId) {
        // 删除角色关联数据
        iBizUserRoleService.deleteBizUserRoleByRoleId(roleId);
        iRoleMenuService.deleteBizRoleMenuByRoleId(roleId);
        iRoleDeptService.deleteBizRoleDeptByRoleId(roleId);
        // 删除角色
        return roleMapper.deleteBizRoleByRoleId(roleId);
    }

    @Override
    public void checkRoleDataScope(Long roleId) {
        Role role = new Role();
        role.setRoleId(roleId);
        List<Role> roles = this.selectBizRoleList(role);
        if (StringUtils.isEmpty(roles)) {
            throw new ServiceException("没有权限访问角色数据！");
        }
    }

    @Override
    public boolean checkRoleNameUnique(Role role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        Role info = roleMapper.checkRoleNameUnique(role.getRoleName());
        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean checkRoleKeyUnique(Role role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        Role info = roleMapper.checkRoleKeyUnique(role.getRoleKey(), role.getTenantId());
        if (ObjectUtil.isNotEmpty(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public Set<String> selectRolePermissionByUserIdAndTenantId(Long userId, String tenantId) {
        List<Role> perms = roleMapper.selectRolePermissionByUserIdAndTenantId(userId, tenantId);
        Set<String> permsSet = new HashSet<>();
        for (Role perm : perms) {
            if (StringUtils.isNotNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    public Set<String> selectRoleKeyByUserIdAndTenantId(Long userId, String tenantId) {
        List<String> strings = roleMapper.selectRoleKeyByUserIdAndTenantId(userId, tenantId);
        return new HashSet<>(strings);
    }

    @Override
    public Set<String> selectRoleKeyByRoleIds(Long[] roleIds) {
        List<String> strings = roleMapper.selectRoleKeyByRoleIds(roleIds);
        return new HashSet<>(strings);
    }

    @Override
    @Transactional
    public int authDataScope(Role role) {
        // 修改角色信息
        roleMapper.updateBizRole(role);
        // 删除角色与部门关联
        iRoleDeptService.deleteBizRoleDeptByRoleId(role.getRoleId());
        // 新增角色和部门信息（数据权限）
        return insertRoleDept(role);
    }

    @Override
    public int updateRoleStatus(Role role) {
        return roleMapper.updateBizRole(role);
    }

    @Override
    public List<Role> selectRoleAll() {
        return this.selectBizRoleList(new Role());
    }

    @Override
    public int deleteAuthUser(UserRole userRole) {
        return iBizUserRoleService.deleteUserRoleInfo(userRole);
    }

    @Override
    public int deleteAuthUsers(Long roleId, Long[] userIds) {
        return iBizUserRoleService.deleteUserRoleInfos(roleId, userIds);
    }

    @Override
    public int insertAuthUsers(Long roleId, Long[] userIds) {
        // 新增用户与角色管理
        List<UserRole> list = new ArrayList<UserRole>();
        for (Long userId : userIds) {
            UserRole ur = new UserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        return iBizUserRoleService.batchUserRole(list);
    }

    @Override
    public int insertRole(Role role) {
        role.setCreateTime(DateUtils.getNowDate());
        return roleMapper.insertBizRole(role);
    }

    @Override
    public boolean checkManageRoleName(Role role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        Role info = roleMapper.checkManageRoleName(role.getRoleName(), role.getTenantId());
        if (ObjectUtil.isNotEmpty(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public List<Role> selectRoleList(Role role) {
        return roleMapper.selectRoleList(role);
    }

    @Override
    public int deleteRoleByRoleIds(Long[] roleIds) {
        // 删除角色与菜单关联
        iRoleMenuService.deleteBizRoleMenuByRoleIds(roleIds);
        // 删除角色与部门关联
        iRoleDeptService.deleteBizRoleDeptByRoleIds(roleIds);
        return roleMapper.deleteBizRoleByRoleIds(roleIds);
    }

    @Override
    public List<Role> selectRolePage(Role role) {
        return roleMapper.selectRolePage(role);
    }

    @Override
    public List<SysMenu> selectMenuList(Long roleId, String serverOwner) {
        Role role = roleMapper.selectBizRoleByRoleId(roleId);
        List<SysMenu> menuList;
        if (StringUtils.isEmpty(role.getTenantId())) {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setServerOwner(serverOwner);
            menuList = menuService.selectMenuList(sysMenu, 1L);
        } else {
            menuList = iTenantMenuService.selectMenuByDepId(role.getTenantId());
        }
        return menuList;
    }

    @Override
    public int editMenuByRole(Role role) {
        // 删除角色和菜单关联数据
        iRoleMenuService.deleteBizRoleMenuByRoleId(role.getRoleId());
        // 批量插入角色和菜单关联数据
        int rows = 1;
        List<RoleMenu> roleMenuList = new ArrayList<>();
        for (Long menuId : role.getMenuIds()) {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(role.getRoleId());
            roleMenu.setMenuId(menuId);
            roleMenuList.add(roleMenu);
        }
        if (!roleMenuList.isEmpty()) {
            rows = iRoleMenuService.insertBatchRoleMenu(roleMenuList);
        }
        return rows;
    }

    @Override
    public boolean checkRoleExistUser(Long roleId) {
        int result = roleMapper.checkRoleExistUser(roleId);
        return result > 0;
    }

    @Override
    public List<Role> selectBizRoleByRoleIds(Long[] roleIds) {
        return roleMapper.selectBizRoleByRoleIds(roleIds);
    }

    @Override
    public List<Role> selectRolesByUserIdAndTenantId(Long userId, String tenantId) {
        return roleMapper.selectRolesByUserIdAndTenantId(userId, tenantId);
    }

    @Override
    public Role selectRoleByAdmin(String tenantId) {
        return roleMapper.selectRoleByAdmin(tenantId);
    }


    /**
     * 新增角色部门信息(数据权限)
     *
     * @param role 角色对象
     */
    public int insertRoleDept(Role role) {
        int rows = 1;
        // 新增角色与部门（数据权限）管理
        List<RoleDept> list = new ArrayList<RoleDept>();
        for (Long deptId : role.getDeptIds()) {
            RoleDept rd = new RoleDept();
            rd.setRoleId(role.getRoleId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        if (!list.isEmpty()) {
            rows = iRoleDeptService.batchRoleDept(list);
        }
        return rows;
    }
}
